package com.baishancloud.log.common.util

import java.text.SimpleDateFormat
import java.time.format.DateTimeFormatter
import java.time.{LocalDateTime, ZoneOffset}
import java.util.Locale

/**
 * 时间相关工具类
 *
 * @author ziqiang.wang 
 * @date 2021/11/17 14:23
 */
object TimeUtil extends Serializable {

  /**
   * 返回当前时间
   *
   * @param format 当前时间的格式
   * @return 指定格式的当前时间
   */
  def now(format: String = "yyyy-MM-dd HH:mm:ss"): String = {
    LocalDateTime.now().format(DateTimeFormatter.ofPattern(format))
  }

  /**
   * 将秒/毫秒转化为字符串
   *
   * @param time   秒/毫秒值
   * @param format 格式，默认为yyyy-MM-dd HH:mm:ss
   * @return 指定格式的字符串
   */
  def longToString(time: Long, format: String = "yyyy-MM-dd HH:mm:ss"): String = {
    val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern(format)
    if (time / 10000000000L > 1) {
      LocalDateTime.ofEpochSecond(time / 1000, 0, ZoneOffset.ofHours(8)).format(formatter)
    } else {
      LocalDateTime.ofEpochSecond(time, 0, ZoneOffset.ofHours(8)).format(formatter)
    }
  }

  /**
   * 将给定字符串格式的时间转化为毫秒值
   *
   * @param time          时间，字符串
   * @param format        格式，默认为yyyy-MM-dd HH:mm:ss
   * @param offsetHourLog 时间补充，小时，默认为int最小值，表示不需要进行时间offset补充。如果时间字符串中包含时区信息，或者是字符串时间就表示东八时区时间，则不需要时间offset补充；否则需要进行offset补充。<br>
   *                      比如日志时间字符串为0时区时间，后面要将其转化为东八时区的时间字符串，则需要补充8小时的时差。
   * @param locale        时间位置，默认为：Locale.ENGLISH
   * @return 毫秒
   */
  def stringToLong(time: String, format: String = "yyyy-MM-dd HH:mm:ss", offsetHourLog: Int = Int.MinValue, locale: Locale = Locale.ENGLISH): Long = {
    new SimpleDateFormat(format, locale).parse(time).getTime + {
      if (offsetHourLog == Int.MinValue) 0 else offsetHourLog * 3600 * 1000L
    }
  }

  /**
   * 根据给定的时间和size进行timeAt计算<br>
   * 注意：两个参数必须同时表示秒或毫秒
   *
   * @param time       日志中的毫秒或秒值
   * @param timeAtSize size，单位：毫秒或秒
   * @return 根据给定的毫秒或秒值及对应size的计算出的timeAt毫秒或秒值
   */
  def timeAtLong(time: Long, timeAtSize: Long): Long = {
    time - time % timeAtSize
  }


  /**
   * 根据给定的时间和size进行timeAt计算<br>
   * 注意：两个参数必须同时表示秒或毫秒
   *
   * @param time       日志中的毫秒或秒值
   * @param timeAtSize size，单位：毫秒或秒
   * @param format     根据给定的毫秒或秒值及对应size的计算出的timeAt的字符串形式，默认为：yyyy-MM-dd HH:mm:ss
   * @return
   */
  def timeAtString(time: Long, timeAtSize: Long, format: String = "yyyy-MM-dd HH:mm:ss"): String = {
    longToString(timeAtLong(time, timeAtSize), format)
  }

  /**
   * 根据给定的时间和size进行timeAt计算<br>
   *
   * @param time          日志中的字符串类型时间
   * @param timeAtSize    size，单位：毫秒
   * @param formatLog     日志中字符串时间格式，默认为：yyyy-MM-dd HH:mm:ss
   * @param offsetHourLog 时间补充，小时，默认为int最小值，表示不需要进行时间offset补充。如果时间字符串中包含时区信息，或者是字符串时间就表示东八时区时间，则不需要时间offset补充；否则需要进行offset补充。<br>
   *                      比如日志时间字符串为0时区时间，后面要将其转化为东八时区的时间字符串，则需要补充8小时的时差。
   * @param locale        日志时间位置，默认为：Locale.ENGLISH
   * @param formatResult  根据给定的毫秒或秒值及对应size的计算出的timeAt的字符串形式，默认为：yyyy-MM-dd HH:mm:ss
   * @return
   */
  def timeAtStringS(time: String, timeAtSize: Long, formatLog: String = "yyyy-MM-dd HH:mm:ss", offsetHourLog: Int = Int.MinValue, locale: Locale = Locale.ENGLISH, formatResult: String = "yyyy-MM-dd HH:mm:ss"): String = {
    longToString(timeAtLong(stringToLong(time, formatLog, offsetHourLog), timeAtSize), formatResult)
  }

}
